package com.duyj.rule.rhino;

import org.mozilla.javascript.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;

/**
 * @author Think
 */
public class ScriptEngine {
    private static final Logger logger = LoggerFactory.getLogger(ScriptEngine.class);
    private static final String RULE_EXECUTE_MAIN_JS_FORMAT = "规则执行的主函数:\n{}";
    /**
     * rhino执行脚本对象
     */
    private Scriptable scope;

    /**
     * rhino执行上下文
     */
    private Context tpContext;

    public ScriptEngine() {
        init();
    }

    public void init() {
        tpContext = Context.enter();
        tpContext.setOptimizationLevel(-1);
        scope = tpContext.initStandardObjects();
    }

    /**
     * 注入系统使用RuleScrpitable注解的类
     */
    public void injectionObjectList(AbstractBizScriptableObject scriptableObject) {
        scope.put(scriptableObject.getObjectName(), scope, scriptableObject);
        String scriptableJs = scriptableObject.getScriptableJs();
        tpContext.evaluateString(scope, scriptableJs, scriptableObject.getObjectName(), 1, null);
    }

    public Object execute(String mainJs) {
        Object tpValue = tpContext.evaluateString(scope, mainJs, null, 1, null);
        if (tpValue instanceof NativeJavaObject) {
            return ((NativeJavaObject) tpValue).unwrap();
        } else if (tpValue instanceof Undefined) {
            throw new RuntimeException("Undefined");
        } else if (tpValue instanceof NativeArray) {
            return new ArrayList<>((NativeArray) tpValue);
        } else {
            return tpValue;
        }
    }
}
